package ar.edu.utn.frba.dds.aterrizar.aerolineas;

import java.util.ArrayList;

import ar.edu.utn.frba.dds.aterrizar.busquedas.Busqueda;
import ar.edu.utn.frba.dds.aterrizar.busquedas.Vuelo;
import ar.edu.utn.frba.dds.aterrizar.usuarios.Usuario;

import com.lanchita.excepciones.CodigoErroneoException;
import com.lanchita.excepciones.EstadoErroneoException;
import com.oceanic.AerolineaOceanic;
import com.oceanic.AsientoDTO;

public class AerolineaOceanicAdapter extends AerolineasInterface {
	

	private static final AerolineaOceanicAdapter INSTANCE = new AerolineaOceanicAdapter();

	private static AerolineaOceanic thisAerolinea;
	public static ArrayList<Vuelo> asientosTotales;

	public static AerolineaOceanicAdapter getInstance() {
		thisAerolinea = AerolineaOceanic.getInstance();
		return INSTANCE;
	}
	
    public AerolineaOceanicAdapter() {
        thisAerolinea = AerolineaOceanic.getInstance();
        }

	public String quienSoy(){
		return "Oceanic";
	}

	@Override
	public void comprarElVuelo(Vuelo vuelo, Usuario usuario){
		if(!thisAerolinea.comprarSiHayDisponibilidad(usuario.getDNI(), vuelo.getCodigoDeVuelo(), Integer.parseInt(vuelo.getCodigoDeAsiento())))
			throw new EstadoErroneoException();
		else
		{
			for (int i = 0; i < AerolineaOceanicAdapter.asientosTotales.size(); i++) 
			{
				if(AerolineaOceanicAdapter.asientosTotales.get(i).getCodigoDeVuelo() == vuelo.getCodigoDeVuelo()
						&& AerolineaOceanicAdapter.asientosTotales.get(i).getCodigoDeAsiento() == vuelo.getCodigoDeAsiento())
				{
					AerolineaOceanicAdapter.asientosTotales.get(i).setDNIcomprador(usuario.getDNI());
					AerolineaOceanicAdapter.asientosTotales.get(i).setEstado("C");
				}
			}
		}
	}

	@Override
	public void reservarElVuelo(Vuelo vuelo, Usuario usuario){
		if(!thisAerolinea.reservar(usuario.getDNI(), vuelo.getCodigoDeVuelo(), Integer.parseInt(vuelo.getCodigoDeAsiento())))
			throw new EstadoErroneoException();
		else
		{
			for (int i = 0; i < AerolineaOceanicAdapter.asientosTotales.size(); i++) 
			{
				if(AerolineaOceanicAdapter.asientosTotales.get(i).getCodigoDeVuelo() == vuelo.getCodigoDeVuelo()
						&& AerolineaOceanicAdapter.asientosTotales.get(i).getCodigoDeAsiento() == vuelo.getCodigoDeAsiento())
				{
					AerolineaOceanicAdapter.asientosTotales.get(i).setDNIcomprador(usuario.getDNI());
					AerolineaOceanicAdapter.asientosTotales.get(i).setEstado("R");
				}
			}
		}
	}

	@Override
	public ArrayList<Vuelo> getAsientosTotales() {
		if(AerolineaOceanicAdapter.asientosTotales == null)
		{
			AerolineaOceanicAdapter.asientosTotales = new ArrayList<Vuelo>();
			for(AsientoDTO asientoDTO : thisAerolinea.getAsientos()){
				AerolineaOceanicAdapter.asientosTotales.add(convertirAsientoAVuelo(asientoDTO));
			}	
		}
		
		return AerolineaOceanicAdapter.asientosTotales;
	}

	@Override
	public ArrayList<Vuelo> getAsientosBuscados(Busqueda busqueda) {
		ArrayList<Vuelo> asientosBuscados = new ArrayList<Vuelo>();
		for(AsientoDTO asientoDTO : thisAerolinea.asientosDisponiblesParaOrigenYDestino(busqueda.getOrigen(), busqueda.getDestino(), busqueda.getRangoFechas().getFechaSalida())){
			asientosBuscados.add(convertirAsientoAVuelo(asientoDTO));
		}		
		return asientosBuscados;
	}

	@Override
	public ArrayList<Vuelo> getAsientosBuscadosIncluyendoReservados(
			Busqueda busqueda) {
		ArrayList<Vuelo> asientosBuscados = new ArrayList<Vuelo>();
		for(AsientoDTO asientoDTO : thisAerolinea.getAsientos()){
			if(asientoDTO.getOrigen().equals(busqueda.getOrigen()) && asientoDTO.getDestino().equals(busqueda.getDestino()) && asientoDTO.getFechaDeSalida().equals(busqueda.getRangoFechas().getFechaSalida()) && asientoDTO.getHoraDeSalida().equals(busqueda.getRangoFechas().getHoraSalida())
					&& asientoDTO.getFechaDeLlegada().equals(busqueda.getRangoFechas().getFechaLlegada()) && asientoDTO.getHoraDeLlegada().equals(busqueda.getRangoFechas().getHoraLlegada())){
						asientosBuscados.add(convertirAsientoAVuelo(asientoDTO));
					}
		}
		return asientosBuscados;
	}

	public Vuelo crearVuelo(AsientoDTO vuelo) {
		return convertirAsientoAVuelo(vuelo);
	}

	protected Vuelo convertirAsientoAVuelo(AsientoDTO asiento){
		String clase = null, ubicacion = null, disponibilidad = "D";
		if(asiento.getClase().equals("Primera")){
			clase = "P";
		}
		if(asiento.getClase().equals("Ejecutiva")){
			clase = "E";
		}
		if(asiento.getClase().equals("Turista")){
			clase = "T";
		}
		if(asiento.getUbicacion().equals("Pasillo")){
			ubicacion = "P";
		}
		if(asiento.getUbicacion().equals("Ventana")){
			ubicacion = "V";
		}
		if(asiento.getUbicacion().equals("Centro")){
			ubicacion = "C";
		}
		if(thisAerolinea.estaComprado(asiento.getCodigoDeVuelo(), asiento.getNumeroDeAsiento())){
			disponibilidad = "C";
		}
		if(thisAerolinea.estaReservado(asiento.getCodigoDeVuelo(), asiento.getNumeroDeAsiento())){
			disponibilidad = "R";
		}
		Vuelo vuelo = new Vuelo(asiento.getCodigoDeVuelo(), Integer.toString(asiento.getNumeroDeAsiento()), asiento.getPrecio().toString(), clase,
				ubicacion, disponibilidad, "", asiento.getHoraDeSalida(), asiento.getHoraDeLlegada(), asiento.getOrigen(), asiento.getDestino(),
				asiento.getFechaDeSalida(), asiento.getFechaDeLlegada(), this);
		return vuelo;
	}

	@Override
	public Vuelo encontrarVueloPorCodigo(Vuelo oVuelo) 
	{
		ArrayList<Vuelo> vuelos = this.getAsientosTotales();
		for(Vuelo vuelo : vuelos) {
			if(vuelo.getCodigoDeVuelo().equalsIgnoreCase(oVuelo.getCodigoDeVuelo()) && vuelo.getCodigoDeAsiento().equalsIgnoreCase(oVuelo.getCodigoDeAsiento())) {
				return vuelo;
			}
		}
		throw new CodigoErroneoException(oVuelo.getCodigoDeVuelo() + "-" + oVuelo.getCodigoDeAsiento());
	}

	
	@Override
	public ArrayList<Vuelo> getReservasPorUsuario(Usuario usuario) {
		return buscarPorEstadoYDNI(usuario, "R");
	}

	@Override
	public ArrayList<Vuelo> getComprasPorUsuario(Usuario usuario) {
		return buscarPorEstadoYDNI(usuario, "C");
	}
	
	private ArrayList<Vuelo> buscarPorEstadoYDNI(Usuario usuario, String estado){
		ArrayList<Vuelo> listaVuelos = new ArrayList<Vuelo>();
		for(Vuelo vuelo : asientosTotales){
			if(vuelo.getDNIcomprador().equals(usuario.getDNI()) && vuelo.getEstado().equals(estado)){
				listaVuelos.add(vuelo);
			}
		}	
		return listaVuelos;
	}
}
